package com.credithc.customers.base.service.impl;

import com.credithc.baseserv.core.convert.BaseConverter;
import com.credithc.baseserv.core.message.MessageFactory;
import com.credithc.baseserv.core.utils.UUIDUtils;
import com.credithc.customers.base.codes.CustomerCodes;
import com.credithc.customers.base.constants.CustomerConstants;
import com.credithc.customers.base.exception.CustomerException;
import com.credithc.customers.base.factory.DictionaryFactory;
import com.credithc.customers.base.mapper.*;
import com.credithc.customers.base.po.*;
import com.credithc.customers.base.ro.*;
import com.credithc.customers.base.service.IBaseCustomerService;
import com.credithc.customers.base.service.ICommonService;
import com.credithc.customers.base.utils.ClassUtils;
import com.credithc.customers.base.utils.CustomerUtils;
import com.credithc.customers.base.vo.CustOauthTokenVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.sql.Date;
import java.sql.Timestamp;
import java.util.*;

/**
 * @author zhukai
 * @date 2018/12/21 11:36
 */
@Service
@Slf4j
public class BaseCustomerServiceImpl implements IBaseCustomerService {

    @Autowired
    private CustomerMapper customerMapper;
    @Autowired
    private CustomerIdInfoMapper customerIdInfoMapper;
    @Autowired
    private CustomerFlowMapper customerFlowMapper;
    @Autowired
    private CustomerContactInfoMapper customerContactInfoMapper;
    @Autowired
    private CustomerExtendMapper customerExtendMapper;
    @Autowired
    private CompanyIdInfoMapper companyIdInfoMapper;
    @Autowired
    private CustomerFlowDetailMapper customerFlowDetailMapper;
    @Autowired
    private CustomerAbnormalMapper abnormalMapper;
    @Autowired
    private BaseConverter<CustomerInfoRo, CustomerFlowPo> converterCustFlowRoToPo;
    @Autowired
    private ICommonService commService;
    @Autowired
    private MessageFactory messageFactory;
    @Autowired
    private CustomerProductMapper customerProductMapper;
    @Autowired
    private CustomerManageInfoMapper customerManageInfoMapper;

    @Override
    public Map<String, String> createCustomerNo(BaseRequest<CustomerInfoRo> request) {
        log.info("【客户开户】接口开始>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>入参:{}", request);
        Integer status = CustomerConstants.STATUS_SUCCESS;
        String errorMsg = null;
        try {
            CustomerInfoRo ro = request.getBody();
            Map<String, String> map = new HashMap<>(2);
            map.put("requestNo", ro.getRequestNo());
            //参数校验
            checkParam(request, false);
            //如果是个人客户开户
            if (CustomerConstants.CUSTOMER_TYPE_PERSON.equals(ro.getCustomerType())) {
                String customerNo = ((BaseCustomerServiceImpl) AopContext.currentProxy()).createPersonNo(request);
                map.put("customerNo", customerNo);
            } else {
                String customerNo = ((BaseCustomerServiceImpl) AopContext.currentProxy()).createCompanyNo(request);
                map.put("customerNo", customerNo);
            }
            return map;
        } catch (CustomerException e) {
            log.error("【客户开户】异常>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{}", e.getMsg());
            status = CustomerConstants.STATUS_FAIL;
            errorMsg = StringUtils.isNotBlank(e.getMsg()) ? e.getMsg() : messageFactory.getInstance(e.getCode()).getMsg();
            throw new CustomerException(e.getCode(), e.getMsg());
        } finally {
            insertCustomerFlow(request, status, errorMsg);
        }
    }

    @Override
    public Map<String, String> createCustomerNo4Import(BaseRequest<CustomerInfoRo> request) {
        log.info("【客户开户】入参>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{}", request);
        try {
            CustomerInfoRo ro = request.getBody();
            Map<String, String> map = new HashMap<>(2);
            map.put("requestNo", ro.getRequestNo());
            //参数校验
            checkParam(request, true);
            //如果是个人客户开户
            if (ro.getCustomerType().equals(CustomerConstants.CUSTOMER_TYPE_PERSON)) {
                String customerNo = ((BaseCustomerServiceImpl) AopContext.currentProxy()).createPersonNo(request);
                map.put("customerNo", customerNo);
            } else {
                String customerNo = ((BaseCustomerServiceImpl) AopContext.currentProxy()).createCompanyNo(request);
                map.put("customerNo", customerNo);
            }
            return map;
        } catch (CustomerException e) {
            log.error("【客户开户】异常>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>{}", e.getMsg());
            throw new CustomerException(e.getCode(), e.getMsg());
        }
    }

    /**
     * @description: 开户参数校验
     * @author: denghx
     * @date: 2018/11/30 11:16
     * @param: request
     * @return: void
     */
    private void checkParam(BaseRequest<CustomerInfoRo> request, boolean isImport) {
        try {
            CustomerInfoRo ro = request.getBody();
            if (!isImport) {
                CustomerInfoRo.checkBaseParam(ro);
                //注掉联系信息验证，很多业务端并不传联系信息
                if (ro.getContacts() == null || ro.getContacts().size() == 0) {
                    log.warn("创建客户号联系信息为空，请求流水号：" + ro.getRequestNo());
//                    throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "联系信息不能为空");
                } else {
                    for (ContactRo contactRo : ro.getContacts()) {
                        ContactRo.checkBaseParam(contactRo);
                    }
                }
                //请求流水号不重复
//                String requestNo = ro.getRequestNo();
//                commService.checkRepeatRequestNo(requestNo, TableEnum.CUSTOMER_FOLW);
            }

            //校验个人客户与企业客户证件必填信息
            String customerType = ro.getCustomerType();
            if (customerType.equals(CustomerConstants.CUSTOMER_TYPE_PERSON)) {
                CustomerIdInfoRo customerIdInfoRo = ro.getIdInfo();
                String customerName = customerIdInfoRo.getCustomerName();
                String idCardType = customerIdInfoRo.getIdCardType();
                String idCardNo = customerIdInfoRo.getIdCardNo();
                //校验证件信息是否规范
                CustomerUtils.checkIdCardTypeAndNo(idCardType, idCardNo);
                if (StringUtils.isBlank(customerName) || StringUtils.isBlank(idCardType) || StringUtils.isBlank(idCardNo)) {
                    throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "证件信息不完善");
                }
            } else if (customerType.equals(CustomerConstants.CUSTOMER_TYPE_COMPANY) || customerType.equals(CustomerConstants.CUSTOMER_TYPE_FINANCE)) {
                CompanyIdInfoRo companyIdInfoRo = ro.getCompanyIdInfo();
                String customerName = companyIdInfoRo.getCustomerName();
                String idCardType = companyIdInfoRo.getIdCardType();
                String idCardNo = companyIdInfoRo.getIdCardNo();
                String orgNo = companyIdInfoRo.getOrgNo();
                String licenseNo = companyIdInfoRo.getLicenseNo();
                String taxNo = companyIdInfoRo.getTaxNo();
                String unifiedCode = companyIdInfoRo.getUnifiedCode();
                if (StringUtils.isBlank(customerName) || StringUtils.isBlank(idCardType) || StringUtils.isBlank(idCardNo)) {
                    throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "法人证件信息不完善");
                }
                if (!(StringUtils.isNotBlank(unifiedCode) || (StringUtils.isNotBlank(orgNo) && StringUtils.isNotBlank(licenseNo) && StringUtils.isNotBlank(taxNo)))) {
                    throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "企业证件信息不完善");
                }
                //todo 证件信息格式校验,为方便测试当前只校验身份证号
//                CustomerUtils.checkIdCardTypeAndNo(idCardType, idCardNo);
            } else {
                //不会到此处
                throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "证件类别(customerType)错误");
            }
            //用户若已转化客户号，则直接返回客户号
            String preCustomerNo = ro.getPreCustomerNo();
            if (StringUtils.isNotBlank(preCustomerNo)) {
                if ((!CustomerConstants.MERCHANTS_EXPECT_LIST.contains(request.getSystemSign()))) {
                    CustomerExtendPo extendPo = commService.getExistPreCustomerExtend(preCustomerNo, request.getSystemSign(), request.getSubSystemSign());
                    if (extendPo == null) {
                        throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_NOT_EXIST, "用户号(preCustomerNo)不存在");
                    }
                }
            }
        } catch (DataAccessException e) {
            log.error("客户开户参数校验报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_QUERY);
        }
    }

    /**
     * @description: 个人客户号开户
     * @author: denghx
     * @date: 2018/11/29 22:18
     * @param: request
     * @return: void
     */
    @Transactional(rollbackFor = Exception.class)
    public String createPersonNo(BaseRequest<CustomerInfoRo> request) {
        try {
            CustomerInfoRo ro = request.getBody();
            CustomerIdInfoRo customerIdInfoRo = ro.getIdInfo();
            CustomerIdInfoPo po = new CustomerIdInfoPo();
            po.setCustomerName(customerIdInfoRo.getCustomerName());
            po.setIdCardType(customerIdInfoRo.getIdCardType());
            po.setIdCardNo(customerIdInfoRo.getIdCardNo());
            //判断三要素是否已存在，存在返回客户号，不存在新增
            List<CustomerIdInfoPo> idInfo = customerIdInfoMapper.select(po);
            String customerNo = null;
            String systemSign = request.getSystemSign();
            String subSystemSign = request.getSubSystemSign();
            String preCustomerNo = ro.getPreCustomerNo();
            String existCustomerNo = null;
            //如果是恒生活实名接口yzt且业务系统标识不为SMZB，accessToken必传，需要转化为用户号preCustomerNo
            if (CustomerConstants.YZT.equals(systemSign) && (!CustomerConstants.SMZB.equals(subSystemSign))) {
                String accessToken = ro.getAccessToken();
                if (StringUtils.isBlank(preCustomerNo)) {
                    if (StringUtils.isBlank(accessToken)) {
                        log.info("创建客户号，accessToken：" + accessToken);
                        throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "accessToken不能为空");
                    }
                    CustOauthTokenVo vo = commService.getOauthTokenInfo(accessToken, subSystemSign);
                    if (vo == null) {
                        throw new CustomerException(CustomerCodes.PARAM_VALIDATE_ERROR, "accessToken不存在");
                    }
                    preCustomerNo = vo.getPreCustomerNo();
                }
                //目前需配置HSH和HENGYIKA实名认证校验
                Map<String, String> checkRuleDictMap = DictionaryFactory.Dict.IDENTIFY_CHECK_RULE.getDictMap();
                String checkRule = checkRuleDictMap.get(subSystemSign);
                if (StringUtils.isNotBlank(checkRule) && (CustomerConstants.IDENTIFY_CHECK.equalsIgnoreCase(checkRule))) {
                    Map<String, String> map = commService.custIdentity(customerIdInfoRo.getIdCardNo(), customerIdInfoRo.getCustomerName());
                    if (!"2010".equals(map.get("resCode"))) {
                        //验证失败
                        throw new CustomerException(CustomerCodes.BIZ_VALIDATE_ERROR, "大数据实名认证失败，返回信息为:" + map.get("resMsg"));
                    }
                }

            }
            //与用户号对应客户号存在，且与idInfo.get(0).getCustomerNo()相同时返回对应客户号，否则抛异常;同一系统，目前同一手机号只允许转化为一个客户号
            // BDSHM不支持一对多
            if (StringUtils.isNotBlank(preCustomerNo) && (!CustomerConstants.MERCHANTS_EXPECT_LIST.contains(systemSign))) {
                CustomerExtendPo customerExtendPo = commService.getExistPreCustomerExtend(preCustomerNo, systemSign, subSystemSign);
                existCustomerNo = customerExtendPo.getCustomerNo();
//                if (!subSystemSign.equals("BDSHM")) {
                if (StringUtils.isNotBlank(existCustomerNo)) {
                    if (idInfo != null && idInfo.size() > 0 && idInfo.get(0).getCustomerNo().equals(existCustomerNo)) {
                        return existCustomerNo;
                    } else {
                        throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_CONVERTED, "用户号转化客户号冲突，该用户号已转化为其它客户号");
                    }
                }

//                else {
//                    if (idInfo != null && idInfo.size() > 0) {
//                        CustomerExtendPo customerExtendPo1 = commService.getExistCustomerExtend(preCustomerNo,idInfo.get(0).getCustomerNo(),systemSign, subSystemSign);
//                        if (customerExtendPo1 != null) {
//                            return customerExtendPo1.getCustomerNo();
//                        }
//                    }
//                }


            }
            //若三要素对应客户号不存在新增，否则直接返回已有客户号
            if (idInfo.size() == 0) {
                customerNo = CustomerUtils.generatePersonalCustomerNo();
                //插入客户主表
                insertCustomerInfo(ro.getCustomerType(), customerNo);
                //插入个人客户证件信息表
                commService.insertCustomerIdInfo(ro.getIdInfo(), customerNo, subSystemSign, ro.getRemark(), false);
                //插入系统标识拆分统计表
                insertCustomerManageInfo(subSystemSign, customerNo);
            } else {
                customerNo = idInfo.get(0).getCustomerNo();
                Boolean custFlag = true;
                List<CustomerManageInfoPo> customerManageInfoPoList = commService.getCustomerManageInfo(customerNo);
                if (customerManageInfoPoList != null && customerManageInfoPoList.size() > 0) {
                    for (CustomerManageInfoPo customerManageInfoPo : customerManageInfoPoList) {
                        if (customerManageInfoPo.getSubSystemSign().equals(subSystemSign)) {
                            custFlag = false;
                        }
                    }
                }
                if (custFlag) {
                    //插入客户号--业务系统关联关系表
                    insertCustomerManageInfo(subSystemSign, customerNo);
                }

            }
            //插入联系信息表
            List<ContactRo> contacts = ro.getContacts();
            if (contacts != null && contacts.size() > 0) {
                List<CustomerContactInfoPo> poList = generateContactList(contacts, customerNo, systemSign, subSystemSign, ro.getRemark());
                for (CustomerContactInfoPo contactPo : poList) {
                    if (commService.getExistCustomerContact(systemSign, subSystemSign, contactPo.getContactType(), contactPo.getContactInfo(), customerNo) == null) {
                        customerContactInfoMapper.insert(contactPo);
                    }
                }
            }
            //若传入用户号，更新客户号与用户号关联表
            if (StringUtils.isNotBlank(preCustomerNo) && (!CustomerConstants.MERCHANTS_EXPECT_LIST.contains(systemSign))) {
                if (StringUtils.isNotBlank(existCustomerNo)) {
                    insertCustomerExtend(systemSign, subSystemSign, null, preCustomerNo, customerNo);
                } else {
                    updateCustomerExtend(systemSign, subSystemSign, customerNo, preCustomerNo);
                }
                //目前暂未使用 更新客户关系表
//                commService.updateRelation(systemSign, subSystemSign, preCustomerNo, customerNo);
//                updateCustomerProduct(systemSign, subSystemSign, preCustomerNo, customerNo);
            }
            //判断相同证件信息有无姓名不同的异常情况，有则存入异常信息表后续维护
//            insertCustomerAbnormal(request, customerNo);
            return customerNo;
        } catch (DataAccessException e) {
            log.error("个人客户创建客户号报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    public void updateCustomerProduct(String systemSign, String subSystemSign, String preCustomerNo, String customerNo) {
        Example example = new Example(CustomerProductInfoPo.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("preCustomerNo", preCustomerNo);
        criteria.andEqualTo("systemSign", systemSign);
        criteria.andEqualTo("subSystemSign", subSystemSign);
        CustomerProductInfoPo po = new CustomerProductInfoPo();
        po.setPreCustomerNo("");
        po.setCustomerNo(customerNo);
        po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        customerProductMapper.updateByExampleSelective(po, example);
    }

    @Transactional(rollbackFor = Exception.class)
    public String createCompanyNo(BaseRequest<CustomerInfoRo> request) {
        try {
            CustomerInfoRo ro = request.getBody();
            String customerNo = null;
            String existCustomerNo = null;
            String systemSign = request.getSystemSign();
            String subSystemSign = request.getSubSystemSign();
            String preCustomerNo = ro.getPreCustomerNo();
            CompanyIdInfoRo companyIdInfoRo = ro.getCompanyIdInfo();
            CompanyIdInfoPo po = new CompanyIdInfoPo();
            po.setUnifiedCode(companyIdInfoRo.getUnifiedCode());
            po.setLicenseNo(companyIdInfoRo.getLicenseNo());
            po.setOrgNo(companyIdInfoRo.getOrgNo());
            po.setTaxNo(companyIdInfoRo.getTaxNo());
            //查询企业三要素
            List<CompanyIdInfoPo> companyIdInfo = companyIdInfoMapper.select(po);
            //与客户号对应客户号已存在，直接返回客户号
            if (StringUtils.isNotBlank(preCustomerNo)) {
                CustomerExtendPo customerExtendPo = commService.getExistPreCustomerExtend(preCustomerNo, systemSign, subSystemSign);
                existCustomerNo = customerExtendPo.getCustomerNo();
                //目前BDSHM不支持一对多,后续需要可放开，但需要评估对cust_extend操作的其它接口的影响
//                if (!subSystemSign.equals("BDSHM")) {
                if (StringUtils.isNotBlank(existCustomerNo)) {
                    if (companyIdInfo != null && companyIdInfo.size() > 0 && companyIdInfo.get(0).getCustomerNo().equals(existCustomerNo)) {
                        return existCustomerNo;
                    } else {
                        throw new CustomerException(CustomerCodes.PRE_CUSTOMERNO_CONVERTED, "用户号转化客户号冲突，该用户号已转化为其它客户号");
                    }
                }
//                }
//                else {
//                    if (companyIdInfo != null && companyIdInfo.size() > 0) {
//                        CustomerExtendPo customerExtendPo1 = commService.getExistCustomerExtend(preCustomerNo,companyIdInfo.get(0).getCustomerNo(),systemSign, subSystemSign);
//                        if (customerExtendPo1 != null) {
//                            return customerExtendPo1.getCustomerNo();
//                        }
//                    }
//                }
            }
            //判断企业客户号是否已存在，存在返回客户号，不存在新增
            if (companyIdInfo.size() == 0) {
                if (ro.getCustomerType().equals(CustomerConstants.CUSTOMER_TYPE_COMPANY)) {
                    customerNo = CustomerUtils.generateCompanyCustomerNo();
                } else {
                    customerNo = CustomerUtils.generateFinancialCustomerNo();
                }
                //插入客户主表
                insertCustomerInfo(ro.getCustomerType(), customerNo);
                //插入企业客户信息表
                commService.insertCompanyIdInfo(companyIdInfoRo, customerNo, subSystemSign);
                //插入系统标识拆分统计表
                insertCustomerManageInfo(subSystemSign, customerNo);
            } else {
                //三要素证件信息是否验核，原先未校验，当前校验则更新;系统标识subSystemSign不存在也新增
                customerNo = companyIdInfo.get(0).getCustomerNo();
                List<CustomerManageInfoPo> customerManageInfoPoList = commService.getCustomerManageInfo(customerNo);
                Boolean custFlag = true;
                if (customerManageInfoPoList != null && customerManageInfoPoList.size() > 0) {
                    for (CustomerManageInfoPo customerManageInfoPo : customerManageInfoPoList) {
                        if (customerManageInfoPo.getSubSystemSign().equals(subSystemSign)) {
                            custFlag = false;
                        }
                    }
                }
                if (custFlag) {
                    //插入系统标识拆分统计表
                    insertCustomerManageInfo(subSystemSign, customerNo);
                }
            }
            //插入联系信息表
            List<ContactRo> contacts = ro.getContacts();
            if (contacts != null && contacts.size() > 0) {
                List<CustomerContactInfoPo> poList = generateContactList(contacts, customerNo, systemSign, subSystemSign, ro.getRemark());
                for (CustomerContactInfoPo contactPo : poList) {
                    if (commService.getExistCustomerContact(systemSign, subSystemSign, contactPo.getContactType(), contactPo.getContactInfo(), customerNo) == null) {
                        customerContactInfoMapper.insert(contactPo);
                    }
                }
            }
            //若传入用户号，更新客户号与用户号关联表
            if (StringUtils.isNotBlank(preCustomerNo)) {
                if (StringUtils.isNotBlank(existCustomerNo)) {
                    insertCustomerExtend(systemSign, subSystemSign, null, preCustomerNo, customerNo);
                } else {
                    updateCustomerExtend(systemSign, subSystemSign, customerNo, preCustomerNo);
                }
                //todo 目前暂未使用
//                commService.updateRelation(systemSign, subSystemSign, preCustomerNo, customerNo);
//                updateCustomerProduct(systemSign, subSystemSign, preCustomerNo, customerNo);
            }
            return customerNo;
        } catch (DataAccessException e) {
            log.error("企业客户开户报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    /**
     * @param status
     * @description: 记录客户开户流水
     * @author: denghx
     * @date: 2018/11/29 17:41
     * @param: request
     * @return: void
     */
    private void insertCustomerFlow(BaseRequest<CustomerInfoRo> request, int status, String errorMessage) {
        try {
            CustomerInfoRo ro = request.getBody();
            CustomerIdInfoRo customerIdInfoRo = ro.getIdInfo();
            CompanyIdInfoRo companyIdInfoRo = ro.getCompanyIdInfo();
            CustomerFlowPo po = converterCustFlowRoToPo.convert(ro, CustomerFlowPo.class);
            po.setId(UUIDUtils.getUUID());
            po.setSystemSign(request.getSystemSign());
            po.setSubSystemSign(request.getSubSystemSign());
            po.setStatus(status);
            CustomerFlowDetailPo flowDetailPo = new CustomerFlowDetailPo();
            List<ContactRo> contacts = ro.getContacts();
            if (contacts != null && contacts.size() > 0) {
                for (ContactRo contact : contacts) {
                    flowDetailPo.setId(UUIDUtils.getUUID());
                    flowDetailPo.setContactInfo(contact.getContactInfo());
                    flowDetailPo.setContactType(contact.getContactType());
                    flowDetailPo.setRequestNo(ro.getRequestNo());
                    flowDetailPo.setCreateTime(new Timestamp(System.currentTimeMillis()));
                    if (contact.getContactVerified() != null) {
                        flowDetailPo.setContactVerified((contact.getContactVerified() ? CustomerConstants.STATUS_CONTACT_VERIFIED : CustomerConstants.STATUS_CONTACT_UNVERIFIED));
                    }
                    customerFlowDetailMapper.insert(flowDetailPo);
                }
            }
            po.setExtend(errorMessage);
            if (ro.getCustomerType().equals(CustomerConstants.CUSTOMER_TYPE_PERSON)) {
                po.setIdCardNo(customerIdInfoRo.getIdCardNo());
                po.setIdCardType(customerIdInfoRo.getIdCardType());
                po.setCustomerName(customerIdInfoRo.getCustomerName());
                if (StringUtils.isNotBlank(customerIdInfoRo.getElementsTime())) {
                    po.setElementsTime(CustomerUtils.stirng2Timestamp(customerIdInfoRo.getElementsTime()));
                }
                po.setElementsVerified((customerIdInfoRo.getElementsVerified() ? CustomerConstants.STATUS_ELEMENTS_VERIFIED : CustomerConstants.STATUS_ELEMENTS_UNVERIFIED));
            } else {
                po.setIdCardNo(companyIdInfoRo.getIdCardNo());
                po.setIdCardType(companyIdInfoRo.getIdCardType());
                po.setCustomerName(companyIdInfoRo.getCustomerName());
                po.setTaxNo(companyIdInfoRo.getTaxNo());
                po.setUnifiedCode(companyIdInfoRo.getUnifiedCode());
                po.setLicenseNo(companyIdInfoRo.getLicenseNo());
                po.setLegalName(companyIdInfoRo.getLegalName());
                po.setOrgNo(companyIdInfoRo.getOrgNo());
                if (StringUtils.isNotBlank(companyIdInfoRo.getElementsTime())) {
                    po.setElementsTime(CustomerUtils.stirng2Timestamp(companyIdInfoRo.getElementsTime()));
                }
                po.setElementsVerified((companyIdInfoRo.getElementsVerified() ? CustomerConstants.STATUS_ELEMENTS_VERIFIED : CustomerConstants.STATUS_ELEMENTS_UNVERIFIED));
            }
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            customerFlowMapper.insert(po);
        } catch (DataAccessException e) {
            log.error("插入客户流水异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    private void insertCustomerInfo(String customerType, String customerNo) {
        try {
            CustomerInfoPo po = new CustomerInfoPo();
            po.setId(UUIDUtils.getUUID());
            po.setCustomerNo(customerNo);
            po.setCustomerType(customerType);
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            po.setCreateDate(new Date(System.currentTimeMillis()));
            customerMapper.insert(po);
        } catch (DataAccessException e) {
            log.info("插入客户基本信息cust_info异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    private static List<CustomerContactInfoPo> generateContactList(List<ContactRo> list, String customerNo, String systemSign, String subSystemSign, String remark) {
        List<CustomerContactInfoPo> resList = new ArrayList<>();
        Map<String, ContactRo> map = new HashMap<>(list.size());
        for (ContactRo ro : list) {
            String contactType = ro.getContactType();
            String contactInfo = ro.getContactInfo();
            CustomerUtils.checkContact(contactType, contactInfo);
            if (map.containsKey(contactInfo)) {
                if (!map.get(contactInfo).getContactType().equals(contactType)) {
                    map.put(contactInfo, ro);
                }
            } else {
                map.put(contactInfo, ro);
            }
        }
        Iterator<Map.Entry<String, ContactRo>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, ContactRo> next = it.next();
            ContactRo value = next.getValue();
            CustomerContactInfoPo po = new CustomerContactInfoPo();
            po.setId(UUIDUtils.getUUID());
            po.setCustomerNo(customerNo);
            po.setContactInfo(value.getContactInfo());
            po.setContactType(value.getContactType());
            //联系方式默认未验证
            po.setContactVerified(value.getContactVerified() != null && value.getContactVerified() ? CustomerConstants.STATUS_CONTACT_VERIFIED : CustomerConstants.STATUS_CONTACT_UNVERIFIED);
            if (StringUtils.isNotBlank(remark)) {
                po.setRemark(remark);
            }
            po.setSystemSign(systemSign);
            po.setSubSystemSign(subSystemSign);
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            resList.add(po);
        }
        return resList;
    }

    @Override
    public void updateCustomerExtend(String systemSign, String subSystemSign, String customerNo, String preCustomerNo) {
        try {
            Example example = new Example(CustomerExtendPo.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("preCustomerNo", preCustomerNo);
            criteria.andEqualTo("systemSign", systemSign);
            criteria.andEqualTo("subSystemSign", subSystemSign);
            criteria.andEqualTo("status", 1);
            //避免其他status影响，仅更新status=1，状态正常的数据
            CustomerExtendPo po = new CustomerExtendPo();
            po.setCustomerNo(customerNo);
            po.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            customerExtendMapper.updateByExampleSelective(po, example);
        } catch (DataAccessException e) {
            log.info("更新cust_extend表异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_UPDATE);
        }
    }

    @Override
    public void insertCustomerExtend(String systemSign, String subSystemSign, String remark, String preCustomerNo, String customerNo) {
        try {
            CustomerExtendPo extendPo = new CustomerExtendPo();
            extendPo.setPreCustomerNo(preCustomerNo);
            extendPo.setSystemSign(systemSign);
            extendPo.setSubSystemSign(subSystemSign);
            extendPo.setCustomerNo(customerNo);
            int res = customerExtendMapper.selectCount(extendPo);
            if (res == 0) {
                extendPo.setId(UUIDUtils.getUUID());
                extendPo.setRemark(remark);
                extendPo.setCreateTime(new Timestamp(System.currentTimeMillis()));
                extendPo.setStatus(1);
                customerExtendMapper.insert(extendPo);
            }
        } catch (DataAccessException e) {
            log.info("插入cust_extend报错:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

    private void insertCustomerAbnormal(BaseRequest<CustomerInfoRo> request, String customerNo) {
        CustomerInfoRo ro = request.getBody();
        CustomerIdInfoRo customerIdInfoRo = ro.getIdInfo();
        CustomerIdInfoPo po = new CustomerIdInfoPo();
        po.setCustomerProperty(CustomerConstants.CUSTOMER_PROPERTY_OFFICIAL);
        po.setIdCardType(customerIdInfoRo.getIdCardType());
        po.setIdCardNo(customerIdInfoRo.getIdCardNo());
        List<CustomerIdInfoPo> tempList = customerIdInfoMapper.select(po);
        if (tempList.size() > 0) {
            List<String> idList = new ArrayList<String>();
            for (CustomerIdInfoPo temp : tempList) {
                if (!(temp.getCustomerName().equals(customerIdInfoRo.getCustomerName()))) {
                    idList.add(temp.getId());
                }
            }
            if (idList.size() > 0) {
                String associatedId = StringUtils.join(idList.toArray(), ",");
                CustomerAbnormalPo abnormalPo = new CustomerAbnormalPo();
                abnormalPo.setCustomerNo(customerNo);
                abnormalPo.setId(UUIDUtils.getUUID());
                abnormalPo.setCustomerName(customerIdInfoRo.getCustomerName());
                abnormalPo.setIdCardNo(customerIdInfoRo.getIdCardNo());
                abnormalPo.setIdCardType(customerIdInfoRo.getIdCardType());
                abnormalPo.setAssociatedId(associatedId);
                abnormalPo.setSystemSign(request.getSystemSign());
                abnormalPo.setSubSystemSign(request.getSubSystemSign());
                abnormalPo.setRequestNo(ro.getRequestNo());
                //默认待处理状态
                abnormalPo.setStatus(CustomerConstants.ABNORMAL_STATUS_TODO);
                //异常类别-客户信息异常
                abnormalPo.setAbnormalType(CustomerConstants.ABNORMAL_TYPE_ERROR);
                abnormalPo.setCreateTime(new Timestamp(System.currentTimeMillis()));
                abnormalMapper.insert(abnormalPo);
            }
        }
    }

    private void insertCustomerManageInfo(String subSystemSign, String customerNo) {
        try {
            CustomerManageInfoPo po = new CustomerManageInfoPo();
            po.setCustomerNo(customerNo);
            po.setSubSystemSign(subSystemSign);
            po.setCreateTime(new Timestamp(System.currentTimeMillis()));
            po.setDate((new Date(System.currentTimeMillis())).toString());
            customerManageInfoMapper.insert(po);
        } catch (DataAccessException e) {
            log.error("插入cust_manage_info表异常:" + ClassUtils.getClassName() + "--" + ClassUtils.getMethodName() + "--" + e.getMessage());
            throw new CustomerException(CustomerCodes.DATABASE_ERROR_INSERT);
        }
    }

}
